<?php
/**
 * Created by PhpStorm.
 * User: Frings
 * Date: 2017/6/1
 * Time: 16:18
 */

namespace app\librarys;


use app\librarys\aliyun_oss\Config;
use app\librarys\aliyun_oss\Core\OssException;
use app\librarys\aliyun_oss\OssClient;
use CURLFile;

/**
 * 上传文件
 * Class FileService
 * @package app\librarys
 */
class FileService
{
    /**
     * 是否使用阿里云OSS存储
     * @return bool
     */
    private static function _isOss()
    {
        return \Yii::$app->params['is_oss'];
    }

    /**
     * 内部文件服务器地址
     * @return string
     */
    private static function _innerFileServiceAddress()
    {
        return \Yii::$app->params['fileService.Address'];
    }

    private static function _innerFileServiceBucketName()
    {
        return \Yii::$app->params['fileService.BucketName'];
    }

    private static function _innerFileServiceEndpoint()
    {
        return \Yii::$app->params['fileService.Endpoint'];
    }

    private static function _innerFileServiceImageEndpoint()
    {
        return \Yii::$app->params['fileService.ImageEndpoint'];
    }

    private static function _innerFileServiceFolder()
    {
        return \Yii::$app->params['fileService.Folder'];
    }

    /**
     * 上传图片到云存储空间
     * @param string $sourceFilePath 本地上传文件路径
     * @param string $destFileName 上传到云上后的文件名
     * @param null|string $destFloderName 上传到云存储空间的文件夹名称
     * @return null|string
     */
    public static function uploadImage($sourceFilePath, $destFileName, $destFloderName = null)
    {
        if (self::_isOss()) {
            return self::_uploadImageAliyun($sourceFilePath, $destFileName, $destFloderName);
        } else {
            return self::_uploadImageInner($sourceFilePath, $destFileName, $destFloderName);
        }
    }

    /**
     * 上传图片到阿里云OSS
     * @param $sourceFilePath
     * @param $destFileName
     * @param null $destFloderName
     * @return null|string
     */
    private static function _uploadImageAliyun($sourceFilePath, $destFileName, $destFloderName = null)
    {
        $imageUrl = null;
        try {
            $ossClient = new OssClient(Config::AccessKeyId(), Config::AccessKeySecret(), 'http://' . Config::OssEndpoint());

            $destFloderPath = Config::Folder() . '/';
            if ($destFloderName != null) {
                $destFloderPath = $destFloderPath . $destFloderName . '/';
            }

            $ossClient->uploadFile(Config::BucketName(), $destFloderPath . $destFileName, $sourceFilePath);
            $imageUrl = 'http://' . Config::BucketName() . '.' . Config::ImageEndpoint() . '/' . $destFloderPath . $destFileName;
        } catch (OssException $e) {
            $imageUrl = null;
        }

        return $imageUrl;
    }

    /**
     * 上传图片到本地内网文件服务器上
     * @param $sourceFilePath
     * @param $destFileName
     * @param null $destFloderName
     * @return null|string
     * @throws \Exception
     */
    private static function _uploadImageInner($sourceFilePath, $destFileName, $destFloderName = null)
    {
        $imageUrl = null;
        if (file_exists($sourceFilePath)) {
            $url = self::_innerFileServiceAddress();
            $destFloderPath = self::_innerFileServiceBucketName() . '/' . self::_innerFileServiceFolder();
            if ($destFloderName != null) {
                $destFloderPath = $destFloderPath . '/' . $destFloderName;
            }

            $data = ['upload_file' => new CURLFile($sourceFilePath), 'dest_file_name' => $destFileName, 'dest_floder_name' => $destFloderPath];
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            $result = curl_exec($curl);
            curl_close($curl);
            if ($result == 0) {
                $imageUrl = self::_innerFileServiceImageEndpoint() . '/' . $destFloderPath . '/' . $destFileName;
            }
        } else {
            throw new \Exception('file not found.');
        }
        return $imageUrl;
    }

    /**
     * 上传文件到云存储空间
     * @param string $sourceFilePath 本地上传文件路径
     * @param string $destFileName 上传到云上后的文件名
     * @param null|string $destFloderName 上传到云存储空间的文件夹名称
     * @return null|string
     */
    public static function uploadFile($sourceFilePath, $destFileName, $destFloderName = null)
    {
        if (self::_isOss()) {
            return self::_uploadFileAliyun($sourceFilePath, $destFileName, $destFloderName);
        } else {
            return self::_uploadFileInner($sourceFilePath, $destFileName, $destFloderName);
        }
    }

    /**
     * 上传文件到阿里云OSS
     * @param $sourceFilePath
     * @param $destFileName
     * @param null $destFloderName
     * @return null|string
     */
    private static function _uploadFileAliyun($sourceFilePath, $destFileName, $destFloderName = null)
    {
        $fileUrl = null;
        try {
            $ossClient = new OssClient(Config::AccessKeyId(), Config::AccessKeySecret(), 'http://' . Config::OssEndpoint());

            $destFloderPath = Config::Folder() . '/';
            if ($destFloderName != null) {
                $destFloderPath = $destFloderPath . $destFloderName . '/';
            }

            $ossClient->uploadFile(Config::BucketName(), $destFloderPath . $destFileName, $sourceFilePath);
            $fileUrl = 'http://' . Config::BucketName() . '.' . Config::OssEndpoint() . '/' . $destFloderPath . $destFileName;
        } catch (OssException $e) {
            $fileUrl = null;
        }

        return $fileUrl;
    }

    /**
     * 上传文件到本地内网文件服务器上
     * @param $sourceFilePath
     * @param $destFileName
     * @param null $destFloderName
     * @return null|string
     * @throws \Exception
     */
    private static function _uploadFileInner($sourceFilePath, $destFileName, $destFloderName = null)
    {
        $fileUrl = null;
        if (file_exists($sourceFilePath)) {
            $url = self::_innerFileServiceAddress();
            $destFloderPath = self::_innerFileServiceBucketName() . '/' . self::_innerFileServiceFolder();
            if ($destFloderName != null) {
                $destFloderPath = $destFloderPath . '/' . $destFloderName;
            }

            $data = ['upload_file' => new CURLFile($sourceFilePath), 'dest_file_name' => $destFileName, 'dest_floder_name' => $destFloderPath];
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            curl_setopt($curl, CURLOPT_POST, true);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
            $result = curl_exec($curl);
            curl_close($curl);
            if ($result == 0) {
                $fileUrl = self::_innerFileServiceEndpoint() . '/' . $destFloderPath . '/' . $destFileName;
            }
        } else {
            throw new \Exception('file not found.');
        }
        return $fileUrl;
    }
}